/*
 * 文件名称:          PropertyValueFilter.java
 * 版权所有@ 2016——2017 无锡聆音科技有限公司，保留所有权利
 * 时间:             2016年7月27日 下午9:21:11
 */
package com.lingyin.json.filter;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.serializer.ValueFilter;

/**
 *  属性值转换，即是对对象中的某个属性值，在json序列化的时候，根据属性值
 *  转换为不同的值或其他对象值。
 *  如domain对象中有int 属性，可以根据需要把该int值转换为string值，甚至其他
 *  需要的对象值。
 * 
 * @项目        jsonlib
 * 
 * @作者:       关宏新
 * 
 * @日期:       2016年7月27日
 * 
 * @负责人:    关宏新
 * 
 * @负责小组:   聆音项目组
 * 
 */
public class PropertyValueFilter implements ValueFilter
{
    // 属性值转换为其他对象，具体转换对象通过method方法进行转换，原属性值为转换方法的最后一个参数，该method必须为静态方法
    private Map<String, Method> methods = new HashMap<String, Method>();
    // 属性值转换中，转换方法的固定参数值
    private Map<String, Object[]> args = new HashMap<String, Object[]>();
    /**
     * 
     */
    public PropertyValueFilter()
    {
    }
    
    /**
     * 
     * @param clazz 需要替换的类
     * @param name 需要替换的属性
     * @param m 需要用什么静态方法获取替换的值
     * @param params 静态方法的参数，这些参数为固定参数，静态方法的最后一个参数为需要替换的原始值，
     * 通过该值，由静态方法获取需要替换的值。
     */
    public void addReplaceMethod(Class<?> clazz, String name, Method m, Object ... params)
    {
        if (clazz == null)
        {
            return;
        }
        String key = clazz.getName() + name;
        methods.put(key, m);
        args.put(key, params);        
    }

    /**
     * 
     * 处理属性值的转换。
     * @param object 需要转换的对象
     * @param name 需要转换的属性名
     * @param value 需要转换的属性值。
     * @return Object 为转换后的属性值。
     */
    public Object process(Object object, String name, Object value)
    {
        String key = object.getClass().getName() + name;
        Method m = methods.get(key);
        if (m != null)
        {
            try
            {
                Object[] temp = args.get(key);
                int length = 0;
                Object[] arg;
                if (temp != null)
                {
                    length = temp.length;
                    arg = new Object[length + 1];
                    System.arraycopy(temp, 0, arg, 0, temp.length);
                }        
                else
                {
                    arg = new Object[length + 1];
                }
                arg[length] = value;
                return m.invoke(null, arg);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
        return value;
    }

}
